package com.ruibang.glass.sale.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.Constants;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.common.domain.DictInfo;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceCreate;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceStatus;
import com.ruibang.glass.common.domain.file.FileBusiness;
import com.ruibang.glass.common.domain.sale.SaleContractManagement;
import com.ruibang.glass.common.utils.ApproveUserNameUtils;
import com.ruibang.glass.frequencycontrol.annotation.RedissonLock;
import com.ruibang.glass.sale.constant.SaleErrorCode;
import com.ruibang.glass.sale.constant.SaleMenuIdCode;
import com.ruibang.glass.sale.domain.req.GSaleOrderReq;
import com.ruibang.glass.sale.dto.FileInfoDTO;
import com.ruibang.glass.sale.dto.GSaleContractManagementDTO;
import com.ruibang.glass.sale.dto.GSaleOrderManagementDTO;
import com.ruibang.glass.sale.dto.GSaleToBeSettledDTO;
import com.ruibang.glass.sale.entity.*;
import com.ruibang.glass.sale.feign.CamundaApi;
import com.ruibang.glass.sale.feign.FileApi;
import com.ruibang.glass.sale.feign.MaterialApi;
import com.ruibang.glass.sale.feign.PortalApi;
import com.ruibang.glass.sale.mapper.*;
import com.ruibang.glass.sale.service.*;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.constant.CommonConstant;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.implementation.bytecode.Throw;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruibang.glass.common.constants.RedisKey.*;


@Slf4j
@Service
public class GSaleOrderManagementServiceImpl extends ServiceImpl<GSaleOrderMapper, GSaleOrderManagement> implements GSaleOrderManagementService {
    @Autowired
    private GSaleOrderProductMapper gSaleOrderProductMapper;

    @Autowired
    private FileApi fileApi;

    @Autowired
    private CommonService commonService;

    @Autowired
    private CamundaApi camundaApi;


    @Autowired
    private RedisSingleService rediservice;

    private static final String finishName = "审批人";

    @Autowired
    private SaleShippingApplicationMapper saleShippingApplicationMapper;

    @Autowired
    private SaleShippingApplicationService saleShippingApplicationService;

    @Autowired
    private GSaleReturnInventoryMapper saleReturnInventoryMapper;

    @Autowired
    private SaleReturnInventoryProductMapper saleReturnInventoryProductMapper;

    @Autowired
    private GSaleCustomerManagementMapper saleCustomerManagementMapper;

    @Autowired
    private GSaleContractManagementMapper saleContractManagementMapper;

    @Autowired
    private GSaleContractProductMapper saleContractProductMapper;

    @Autowired
    private MaterialApi materialApi;

    private static final String SALE_OUT_NUMBER = "sale_out_number";
    @Autowired
    private PortalApi portalApi;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Override
    public IPage<GSaleOrderManagement> getPage(GSaleOrderReq gSaleOrderReq) {
        IPage<GSaleOrderManagement> page = baseMapper.getPage(new Page<>(gSaleOrderReq.getPageNo(), gSaleOrderReq.getPageSize()), gSaleOrderReq);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return page;
        }
        Map<Object, Object> userMap = rediservice.hmget(RedisKey.USER_GROUP_TYPE);
        List<String> businessKeys = page.getRecords().stream().map(GSaleOrderManagement::getId).collect(Collectors.toList());
        Map<String, BpmProcessInstanceStatus> processMap = null;
        //获取业务流程状态
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(businessKeys);
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            processMap = resultBody.getData().stream().collect(Collectors.toMap(bp -> bp.getBusinessKey(), bp -> bp, (bp1, bp2) -> bp1));
        }

        Map<String, String> CustomerManagementsMap = new HashMap<>();
        List<GSaleCustomerManagement> gSaleCustomerManagements = saleCustomerManagementMapper.selectList();
        for (GSaleCustomerManagement saleCustomerManagement : gSaleCustomerManagements) {
            CustomerManagementsMap.put(saleCustomerManagement.getId(), saleCustomerManagement.getCustomerName());
        }
        if (CustomerManagementsMap != null) {
            for (GSaleOrderManagement saleOrderManagement : page.getRecords()) {
                if (StringUtils.isNotEmpty(CustomerManagementsMap.get(saleOrderManagement.getConsignorSettlementCustomer()))) {
                    saleOrderManagement.setConsignorSettlementCustomer(CustomerManagementsMap.get(saleOrderManagement.getConsignorSettlementCustomer()));
                }
                if (StringUtils.isNotEmpty(CustomerManagementsMap.get(saleOrderManagement.getConsigneeCustomer()))) {
                    saleOrderManagement.setConsigneeCustomer(CustomerManagementsMap.get(saleOrderManagement.getConsigneeCustomer()));
                }

            }
        }

        if (processMap != null) {
            for (GSaleOrderManagement saleOrderManagement : page.getRecords()) {
                if (processMap.get(saleOrderManagement.getId()) != null) {
                    saleOrderManagement.setStatus(saleOrderManagement.getApproveStatus());
                    saleOrderManagement.setProcessId(processMap.get(saleOrderManagement.getId()).getProcessInstanceId());
//                    saleOrderManagement.setApproveStatus(processMap.get(saleOrderManagement.getId()).getResult());
                    saleOrderManagement.setNodeName(processMap.get(saleOrderManagement.getId()).getNodeName());
                    String userId = processMap.get(saleOrderManagement.getId()).getUserId();
                    if (StringUtils.isNotBlank(userId) && !StringUtils.equals(userId, "null")) {
                        saleOrderManagement.setApproveUserId(userId);
                        String approveName = ApproveUserNameUtils.getApproveName(userId, userMap);
                        saleOrderManagement.setApproveUser(approveName);
                    }
                }

            }
        }

        return page;
    }

    @Override
    public IPage<GSaleToBeSettledDTO> getGSaleToBeSettledDTOPage(GSaleOrderReq gSaleOrderReq) {
        Map<Object, Object> userMap = rediservice.hmget(RedisKey.USER_GROUP_TYPE);
        IPage<GSaleToBeSettledDTO> gSaleToBeSettledDTOPage = baseMapper.getGSaleToBeSettledDTOPage(new Page<>(gSaleOrderReq.getPageNo(), gSaleOrderReq.getPageSize()), gSaleOrderReq);
        if (CollectionUtils.isNotEmpty(gSaleToBeSettledDTOPage.getRecords())) {
            List<String> collect = gSaleToBeSettledDTOPage.getRecords().stream().map(GSaleToBeSettledDTO::getCustomerName).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                List<GSaleCustomerManagement> gSaleCustomerManagements = saleCustomerManagementMapper.selectBatchIds(collect);
                for (GSaleToBeSettledDTO saleToBeSettledDTO : gSaleToBeSettledDTOPage.getRecords()) {
                    for (GSaleCustomerManagement saleCustomerManagement : gSaleCustomerManagements) {
                        if (StringUtils.equals(saleToBeSettledDTO.getCustomerName(), saleCustomerManagement.getId())) {
                            saleToBeSettledDTO.setCustomerName(saleCustomerManagement.getCustomerName());
                        }
                        if (userMap.get(saleToBeSettledDTO.getCreateUserId()) != null) {
                            saleToBeSettledDTO.setCreateUserName((String) userMap.get(saleToBeSettledDTO.getCreateUserId()));
                        }
                    }
                }
            }
        }
        return gSaleToBeSettledDTOPage;
    }


    @Override
//    @Transactional(rollbackFor = Exception.class)
    public void addGSaleOrderManagement(GSaleOrderManagement gSaleOrderManagement) {
        if (CollectionUtils.isEmpty(gSaleOrderManagement.getSaleOrderProductList())) {
            throw new ServiceException(SaleErrorCode.NEW_ORDER_NO_ITEM.getCode(), SaleErrorCode.NEW_ORDER_NO_ITEM.getMsg());
        }

        String status = transactionTemplate.execute(tran -> {
            GSaleContractManagement gSaleContractManagement = saleContractManagementMapper.selectById(gSaleOrderManagement.getContractId());
            if (gSaleContractManagement == null) {
                baseMapper.insert(gSaleOrderManagement);
                if (CollectionUtils.isNotEmpty(gSaleOrderManagement.getFileList())) {
                    FileBusiness fileBusiness = new FileBusiness();
                    fileBusiness.setFileIds(gSaleOrderManagement.getFileList());
                    fileBusiness.setBusinessId(gSaleOrderManagement.getId());
                    fileApi.updateBusinessById(fileBusiness);
                }
                BigDecimal countTotal = BigDecimal.ZERO;
                for (GSaleOrderProduct gSaleOrderProduct : gSaleOrderManagement.getSaleOrderProductList()) {
                    if (gSaleOrderProduct.getOrderQuantity() == null) {
                        throw new ServiceException(SaleErrorCode.NO_QUALITY.getCode(), SaleErrorCode.NO_QUALITY.getMsg());
                    }
                    countTotal = countTotal.add(gSaleOrderProduct.getOrderQuantity());
                    gSaleOrderProduct.setOrderId(gSaleOrderManagement.getId());
                    gSaleOrderProductMapper.insert(gSaleOrderProduct);
                }
                gSaleOrderManagement.setTotalQuantity(countTotal);
                gSaleOrderManagement.setPendingDelivery(countTotal);
                gSaleOrderManagement.setDelivered(BigDecimal.ZERO);
                gSaleOrderManagement.setReturnQuantity(BigDecimal.ZERO);
                gSaleOrderManagement.setExchangeQuantity(BigDecimal.ZERO);
                baseMapper.updateById(gSaleOrderManagement);
            } else {
                GSaleContractProduct saleContractProduct = saleContractProductMapper.selectOne(Wrappers.<GSaleContractProduct>lambdaQuery()
                        .eq(GSaleContractProduct::getContractId, gSaleContractManagement.getId())
                        .eq(GSaleContractProduct::getProductId, gSaleOrderManagement.getSaleOrderProductList().get(0).getProductId())
                        .last("limit 1")
                );
                if (saleContractProduct.getUseQuantity() == null) {
                    saleContractProduct.setUseQuantity(BigDecimal.ZERO);
                }
                BigDecimal add1 = saleContractProduct.getUseQuantity().add(gSaleOrderManagement.getSaleOrderProductList().get(0).getOrderQuantity());
                if (saleContractProduct.getQuantity() == null) {

                } else {
                    if (saleContractProduct.getQuantity().compareTo(add1) < 0) {
                        throw new ServiceException(SaleErrorCode.ORDER_QUALITY_MORE_CONTRACT_QUALITY.getCode(), SaleErrorCode.ORDER_QUALITY_MORE_CONTRACT_QUALITY.getMsg());
                    }
                }
                saleContractProduct.setUseQuantity(add1);
                saleContractProductMapper.updateById(saleContractProduct);
                BigDecimal add = BigDecimal.ZERO;
                if (gSaleContractManagement.getContractType().equals(Constants.TWO_STR) || gSaleContractManagement.getContractType().equals(Constants.THREE_STR)) {

                    if (gSaleOrderManagement.getSaleOrderProductList().get(0).getOrderQuantity() == null) {
                        throw new ServiceException(SaleErrorCode.NO_QUALITY.getCode(), SaleErrorCode.NO_QUALITY.getMsg());
                    }
                    GSaleOrderProduct gSaleOrderProduct1 = gSaleOrderManagement.getSaleOrderProductList().get(0);

                    if (gSaleContractManagement.getOrderQuantity() == null) {
                        throw new ServiceException(SaleErrorCode.CONTRACT_NO_QUALITY.getCode(), SaleErrorCode.CONTRACT_NO_QUALITY.getMsg());
                    }
                    if (gSaleContractManagement.getOrderUseQuantity() == null) {
                        add = gSaleOrderProduct1.getOrderQuantity().add(BigDecimal.ZERO);
                    } else {
                        add = gSaleOrderProduct1.getOrderQuantity().add(gSaleContractManagement.getOrderUseQuantity());
                    }
                    if (add.compareTo(gSaleContractManagement.getOrderQuantity()) > 0) {
                        throw new ServiceException(SaleErrorCode.ORDER_QUALITY_MORE_CONTRACT_QUALITY.getCode(), SaleErrorCode.ORDER_QUALITY_MORE_CONTRACT_QUALITY.getMsg());
                    }
                }
                if (gSaleContractManagement.getContractType().equals(Constants.TWO_STR) || gSaleContractManagement.getContractType().equals(Constants.THREE_STR)) {
                    gSaleContractManagement.setOrderUseQuantity(add);
                    saleContractManagementMapper.updateById(gSaleContractManagement);
                }
                gSaleOrderManagement.setApproveStatus(Constants.ZERO_STR);
//                if (StringUtils.isNotEmpty(gSaleOrderManagement.getRelatedMultipleOrders())) {
//                    SaleShippingApplication saleShippingApplication = saleShippingApplicationMapper.selectById(gSaleOrderManagement.getRelatedMultipleOrders());
//                    saleShippingApplication.setCollectionStatus(Constants.TWO_STR);
//                    saleShippingApplicationMapper.updateById(saleShippingApplication);
//                }
                baseMapper.insert(gSaleOrderManagement);
                BigDecimal countTotal = BigDecimal.ZERO;
                for (GSaleOrderProduct gSaleOrderProduct : gSaleOrderManagement.getSaleOrderProductList()) {
                    if (gSaleOrderProduct.getOrderQuantity() == null) {
                        throw new ServiceException(SaleErrorCode.NO_QUALITY.getCode(), SaleErrorCode.NO_QUALITY.getMsg());
                    }
                    countTotal = countTotal.add(gSaleOrderProduct.getOrderQuantity());
                    gSaleOrderProduct.setOrderId(gSaleOrderManagement.getId());
                    gSaleOrderProductMapper.insert(gSaleOrderProduct);
                }

                gSaleOrderManagement.setTotalQuantity(countTotal);
                gSaleOrderManagement.setPendingDelivery(countTotal);
                gSaleOrderManagement.setDelivered(BigDecimal.ZERO);
                gSaleOrderManagement.setReturnQuantity(BigDecimal.ZERO);
                gSaleOrderManagement.setExchangeQuantity(BigDecimal.ZERO);

                if (StringUtils.isNotEmpty(gSaleOrderManagement.getRelatedMultipleOrders())) {
                    GSaleOrderManagement saleOrderManagement = baseMapper.selectById(gSaleOrderManagement.getRelatedMultipleOrders());
                    BigDecimal subtract = saleOrderManagement.getDelivered().subtract(saleOrderManagement.getTotalQuantity());
                    if (gSaleOrderManagement.getTotalQuantity().compareTo(subtract) < 0) {
                        throw new ServiceException(SaleErrorCode.UNION_ORDER_MORE_ORDER.getCode(), SaleErrorCode.UNION_ORDER_MORE_ORDER.getMsg());
                    } else {
                        gSaleOrderManagement.setDelivered(subtract);
                        saleOrderManagement.setCollectionStatus(Constants.TWO_STR);
                        baseMapper.updateById(saleOrderManagement);
                    }
                }

                baseMapper.updateById(gSaleOrderManagement);
                if (CollectionUtils.isNotEmpty(gSaleOrderManagement.getFileList())) {
                    FileBusiness fileBusiness = new FileBusiness();
                    fileBusiness.setFileIds(gSaleOrderManagement.getFileList());
                    fileBusiness.setBusinessId(gSaleOrderManagement.getId());
                    fileApi.updateBusinessById(fileBusiness);
                }
                if (StringUtils.isBlank(gSaleOrderManagement.getMenuId())) {
                    gSaleOrderManagement.setMenuId(SaleMenuIdCode.MENU_IN_SALE_SHIPPING.getMsg());
                }
            }
            return Constants.ONE_STR;
        });

        if (Constants.ONE_STR.equals(status)) {
            BpmProcessInstanceCreate instanceCreate = new BpmProcessInstanceCreate();
            instanceCreate.setBusinessKey(gSaleOrderManagement.getId());
            instanceCreate.setMenuId(gSaleOrderManagement.getMenuId());
            //发起流程
            if (StringUtils.isNotBlank(gSaleOrderManagement.getCreateUserId())) {
                Map<String, Object> variables = new HashMap<>();
                variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_STARTER_USER_ID, gSaleOrderManagement.getCreateUserId());
                variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_BUSINESS_KEY, gSaleOrderManagement.getId());
                variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_MENU_ID, gSaleOrderManagement.getMenuId());
                instanceCreate.setVariables(variables);
            }
            commonService.startProcess(instanceCreate);
        }

    }

    @Override
    public void processNotice(String businessId) {
        //
        GSaleOrderManagement saleOrderManagement = baseMapper.selectById(businessId);
        //销售订单驳回
        if (saleOrderManagement.getApproveStatus().equals(Constants.FOUR_STR)) {
            GSaleContractManagement gSaleContractManagement = saleContractManagementMapper.selectById(saleOrderManagement.getContractId());
            //获取之前的数量
            GSaleOrderProduct gSaleOrderProduct2 = gSaleOrderProductMapper.selectOne(Wrappers.<GSaleOrderProduct>lambdaQuery().eq(GSaleOrderProduct::getOrderId, businessId)
                    .last("limit 1"));
            GSaleContractProduct saleContractProduct = saleContractProductMapper.selectOne(Wrappers.<GSaleContractProduct>lambdaQuery()
                    .eq(GSaleContractProduct::getContractId, gSaleContractManagement.getId())
                    .eq(GSaleContractProduct::getProductId, gSaleOrderProduct2.getProductId())
                    .last("limit 1")
            );
            if (saleContractProduct.getUseQuantity() == null) {
                saleContractProduct.setUseQuantity(BigDecimal.ZERO);
            }
            if (!StringUtils.equals(gSaleContractManagement.getContractType(), Constants.ONE_STR)) {
                BigDecimal subtract = saleContractProduct.getUseQuantity().subtract(gSaleOrderProduct2.getOrderQuantity());
                saleContractProduct.setUseQuantity(subtract);
                saleContractProductMapper.updateById(saleContractProduct);

                BigDecimal subtract1 = gSaleContractManagement.getOrderUseQuantity().subtract(gSaleOrderProduct2.getOrderQuantity());
                gSaleContractManagement.setOrderUseQuantity(subtract1);
                saleContractManagementMapper.updateById(gSaleContractManagement);
            }
            saleOrderManagement.setStatus(Constants.TEN_STR);
            saleOrderManagement.setTotalQuantity(BigDecimal.ZERO);
            saleOrderManagement.setPendingDelivery(BigDecimal.ZERO);
            saleOrderManagement.setDelivered(BigDecimal.ZERO);
            baseMapper.updateById(saleOrderManagement);
        }


        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(Arrays.asList(businessId));
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            BpmProcessInstanceStatus process = resultBody.getData().get(0);
            if (saleOrderManagement.getApproveStatus().equals(Constants.TWO_STR)) {
                List<SaleShippingApplication> saleShippingApplications = new ArrayList<>();
//                GSaleOrderManagement saleOrderManagement = baseMapper.selectById(businessId);
                GSaleOrderProduct gSaleOrderProduct = gSaleOrderProductMapper.selectOne(Wrappers.<GSaleOrderProduct>lambdaQuery().eq(GSaleOrderProduct::getOrderId, businessId).last("limit 1"));
                SaleShippingApplication saleShippingApplication = new SaleShippingApplication();
                BeanUtils.copyProperties(saleOrderManagement, saleShippingApplication);
                if (saleOrderManagement.getDelivered() != null) {
                    BigDecimal subtract = saleOrderManagement.getTotalQuantity().subtract(saleOrderManagement.getDelivered());
                    saleOrderManagement.setDelivered(subtract);
                }
                saleShippingApplication.setId("");
                saleShippingApplication.setApprovalStatus(Constants.ZERO_STR);
                saleShippingApplication.setApproveStatus(Constants.ZERO_STR);
                saleShippingApplication.setSpecification(gSaleOrderProduct.getProductSpecification());
                saleShippingApplication.setProductType(saleOrderManagement.getProductCategory());
                saleShippingApplication.setDeliveryOrderNumber(getMaterialShppingNumber());
                saleShippingApplication.setOutboundNumber(getMaterialOUTNumber());
                saleShippingApplication.setLogisticsNumber(StringDGGeneratorService.generateString());
                saleShippingApplication.setOrderId(saleOrderManagement.getId());
                saleShippingApplication.setProductName(gSaleOrderProduct.getProductName());
                saleShippingApplication.setProductId(gSaleOrderProduct.getProductId());
                saleShippingApplication.setShippingDate(saleOrderManagement.getDeliveryDate());
                saleShippingApplication.setExecutionStandard(gSaleOrderProduct.getExecutionStandard());
                saleShippingApplication.setOrderingSettlementCustomer(saleOrderManagement.getConsignorSettlementCustomer());
                saleShippingApplication.setDemandCustomer(saleOrderManagement.getConsigneeCustomer());
                saleShippingApplication.setTotalQuantity(gSaleOrderProduct.getOrderQuantity());
                saleShippingApplication.setProductType(saleOrderManagement.getProductCategory());
                saleShippingApplication.setCreateUserId(saleOrderManagement.getCreateUserId());
                saleShippingApplication.setGrade(gSaleOrderProduct.getGrade());
                saleShippingApplication.setPendingShipment(gSaleOrderProduct.getOrderQuantity());
                saleShippingApplication.setTotalQuantity(gSaleOrderProduct.getOrderQuantity());
                saleShippingApplication.setCancelledQuantity(BigDecimal.ZERO);
                saleShippingApplication.setReturnedQuantity(BigDecimal.ZERO);
                saleShippingApplication.setShippedQuantity(BigDecimal.ZERO);
                saleShippingApplication.setCompletionRate(BigDecimal.ZERO);
                saleShippingApplication.setExchangedQuantity(BigDecimal.ZERO);
                saleShippingApplication.setGrossUnitPrice(gSaleOrderProduct.getGrossUnitPrice());
                saleShippingApplication.setGrossAmount(gSaleOrderProduct.getGrossAmount());
                saleShippingApplication.setNetUnitPrice(gSaleOrderProduct.getNetUnitPrice());
                saleShippingApplication.setNetAmount(gSaleOrderProduct.getNetAmount());
                saleShippingApplication.setOtherMarkup(gSaleOrderProduct.getOtherMarkup());
                saleShippingApplication.setBulkDiscountPrice(gSaleOrderProduct.getBulkDiscountPrice());
                saleShippingApplication.setTransportAmount(gSaleOrderProduct.getTransportAmount());
                saleShippingApplication.setTotalAmount(gSaleOrderProduct.getTotalAmount());
                saleShippingApplication.setNetTotalAmount(gSaleOrderProduct.getNetTotalAmount());
                saleShippingApplication.setTaxAmount(gSaleOrderProduct.getTaxAmount());
                saleShippingApplications.add(saleShippingApplication);
                saleShippingApplicationService.addSaleShippingApplication(saleShippingApplications);
            }
        }
    }

    @RedissonLock(key = MATERIAL_IN_WAREHOUSE_NUMBER, prefixKey = "lock_")
    public String getMaterialOUTNumber() {
        String date = LocalDate.now().format(DateTimeFormatter.ofPattern(CommonConstant.DATE_FORMAT_UN_SEPARATE));
        date = "OUT".concat(date);
        String code = "";

        Serializable number = rediservice.get(RedisKey.MATERIAL_OUT_WAREHOUSE_NUMBER);
        if (number == null || StringUtils.isBlank(number.toString())) {
            ResultBody<String> resultBody = portalApi.getValueByCode(SALE_OUT_NUMBER);
            if (resultBody != null && StringUtils.isNotBlank(resultBody.getData())) {
                number = resultBody.getData();
            }
        }
        if (number != null && StringUtils.isNotBlank(number.toString()) && number.toString().length() > 11) {
            String sequenceStr = number.toString().substring(11);
            int sequenceInt = Integer.parseInt(sequenceStr);
            sequenceInt = sequenceInt + 1;
            String newSequence = String.valueOf(sequenceInt);
            if (newSequence.length() == CommonConstant.FIVE_INT) {
                code = date.concat("0001");
            } else {
                code = date.concat(String.format("%04d", sequenceInt)); // 格式化数字为4位，不足部分用0填充
            }
        } else {
            code = date.concat("0001");
        }
        rediservice.set(RedisKey.MATERIAL_OUT_WAREHOUSE_NUMBER, code);
        DictInfo info = new DictInfo();
        info.setCsdm(RedisKey.MATERIAL_OUT_WAREHOUSE_NUMBER);
        info.setCsmc(code);
        portalApi.updateValueByCode(info);
        return code;
    }

    /**
     * 当订单审批结束 生成销售发货
     *
     * @param gSaleOrderManagement
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGSaleOrderManagement(GSaleOrderManagement gSaleOrderManagement) {
        if (CollectionUtils.isEmpty(gSaleOrderManagement.getSaleOrderProductList())) {
            throw new ServiceException(SaleErrorCode.NEW_ORDER_NO_ITEM.getCode(), SaleErrorCode.NEW_ORDER_NO_ITEM.getMsg());
        }
        GSaleOrderManagement saleOrderManagement = baseMapper.selectById(gSaleOrderManagement.getId());
        //取消关联多发货
        if (StringUtils.isNotEmpty(saleOrderManagement.getRelatedMultipleOrders())) {
            GSaleOrderManagement saleOrderManagement1 = baseMapper.selectById(saleOrderManagement.getRelatedMultipleOrders());
            saleOrderManagement1.setCollectionStatus(Constants.ONE_STR);
            saleOrderManagement.setDelivered(BigDecimal.ZERO);
            baseMapper.updateById(saleOrderManagement1);
            baseMapper.updateById(saleOrderManagement);
        }

        //再次关联多发货

        GSaleContractManagement gSaleContractManagement = saleContractManagementMapper.selectById(saleOrderManagement.getContractId());
        if (gSaleContractManagement == null) {
            fileApi.deleteByBusinessId(gSaleOrderManagement.getId());
            if (CollectionUtils.isNotEmpty(gSaleOrderManagement.getFileList())) {
                FileBusiness fileBusiness = new FileBusiness();
                fileBusiness.setFileIds(gSaleOrderManagement.getFileList());
                fileBusiness.setBusinessId(gSaleOrderManagement.getId());
                fileApi.updateBusinessById(fileBusiness);
            }
            gSaleOrderProductMapper.delete(Wrappers.<GSaleOrderProduct>lambdaQuery().eq(GSaleOrderProduct::getOrderId, gSaleOrderManagement.getId()));
            List<GSaleOrderProduct> saleOrderProductList = gSaleOrderManagement.getSaleOrderProductList();

            BigDecimal countTotal = BigDecimal.ZERO;
            for (GSaleOrderProduct gSaleOrderProduct : gSaleOrderManagement.getSaleOrderProductList()) {
                if (gSaleOrderProduct.getOrderQuantity() == null) {
                    throw new ServiceException(SaleErrorCode.NO_QUALITY.getCode(), SaleErrorCode.NO_QUALITY.getMsg());
                }
                countTotal = countTotal.add(gSaleOrderProduct.getOrderQuantity());
                gSaleOrderProduct.setOrderId(gSaleOrderManagement.getId());
                gSaleOrderProductMapper.insert(gSaleOrderProduct);
            }
            gSaleOrderManagement.setTotalQuantity(countTotal);
            gSaleOrderManagement.setPendingDelivery(countTotal);
            gSaleOrderManagement.setDelivered(BigDecimal.ZERO);
            gSaleOrderManagement.setReturnQuantity(BigDecimal.ZERO);
            gSaleOrderManagement.setExchangeQuantity(BigDecimal.ZERO);
            baseMapper.updateById(gSaleOrderManagement);
            return;
        }

        //获取之前的数量
        GSaleOrderProduct gSaleOrderProduct2 = gSaleOrderProductMapper.selectOne(Wrappers.<GSaleOrderProduct>lambdaQuery().eq(GSaleOrderProduct::getOrderId, gSaleOrderManagement.getId())
                .last("limit 1"));


        GSaleContractProduct saleContractProduct = saleContractProductMapper.selectOne(Wrappers.<GSaleContractProduct>lambdaQuery()
                .eq(GSaleContractProduct::getContractId, gSaleContractManagement.getId())
                .eq(GSaleContractProduct::getProductId, gSaleOrderProduct2.getProductId())
                .last("limit 1")
        );

        if (saleContractProduct.getUseQuantity() == null) {
            saleContractProduct.setUseQuantity(BigDecimal.ZERO);
        }

        BigDecimal subtract = saleContractProduct.getUseQuantity().subtract(gSaleOrderProduct2.getOrderQuantity());
        saleContractProduct.setUseQuantity(subtract);
        saleContractProductMapper.updateById(saleContractProduct);

        GSaleContractManagement gSaleContractManagementNow = saleContractManagementMapper.selectById(gSaleOrderManagement.getContractId());

        GSaleContractProduct saleContractProductNow = saleContractProductMapper.selectOne(Wrappers.<GSaleContractProduct>lambdaQuery()
                .eq(GSaleContractProduct::getContractId, gSaleContractManagementNow.getId())
                .eq(GSaleContractProduct::getProductId, gSaleOrderManagement.getSaleOrderProductList().get(0).getProductId())
                .last("limit 1")
        );
        if (saleContractProductNow.getUseQuantity() == null) {
            saleContractProductNow.setUseQuantity(BigDecimal.ZERO);
        }
        BigDecimal add1 = saleContractProductNow.getUseQuantity().add(gSaleOrderManagement.getSaleOrderProductList().get(0).getOrderQuantity());
        if (saleContractProduct.getQuantity() == null) {

        } else {
            if (saleContractProduct.getQuantity().compareTo(add1) < 0) {
                throw new ServiceException(SaleErrorCode.ORDER_QUALITY_MORE_CONTRACT_QUALITY.getCode(), SaleErrorCode.ORDER_QUALITY_MORE_CONTRACT_QUALITY.getMsg());
            }
        }
        saleContractProductNow.setUseQuantity(add1);
        saleContractProductMapper.updateById(saleContractProductNow);

        BigDecimal add = BigDecimal.ZERO;
        if (gSaleContractManagement.getContractType().equals(Constants.TWO_STR) || gSaleContractManagement.getContractType().equals(Constants.THREE_STR)) {
            if (CollectionUtils.isEmpty(gSaleOrderManagement.getSaleOrderProductList())) {
                throw new ServiceException(SaleErrorCode.NEW_ORDER_NO_ITEM.getCode(), SaleErrorCode.NEW_ORDER_NO_ITEM.getMsg());
            }
            if (gSaleOrderManagement.getSaleOrderProductList().get(0).getOrderQuantity() == null) {
                throw new ServiceException(SaleErrorCode.NO_QUALITY.getCode(), SaleErrorCode.NO_QUALITY.getMsg());
            }
            GSaleOrderProduct gSaleOrderProduct1 = gSaleOrderManagement.getSaleOrderProductList().get(0);

            if (gSaleContractManagement.getOrderQuantity() == null) {
                throw new ServiceException(SaleErrorCode.CONTRACT_NO_QUALITY.getCode(), SaleErrorCode.CONTRACT_NO_QUALITY.getMsg());
            }

            if (gSaleContractManagement.getOrderUseQuantity() == null) {
                add = gSaleOrderProduct1.getOrderQuantity().add(BigDecimal.ZERO);
            } else {
                add = gSaleOrderProduct1.getOrderQuantity().add(gSaleContractManagement.getOrderUseQuantity()).subtract(gSaleOrderManagement.getTotalQuantity());
            }

            if (add.compareTo(gSaleContractManagement.getOrderQuantity()) > 0) {
                throw new ServiceException(SaleErrorCode.ORDER_QUALITY_MORE_CONTRACT_QUALITY.getCode(), SaleErrorCode.ORDER_QUALITY_MORE_CONTRACT_QUALITY.getMsg());
            }
        }

        if (gSaleContractManagement.getContractType().equals(Constants.TWO_STR) || gSaleContractManagement.getContractType().equals(Constants.THREE_STR)) {
            gSaleContractManagement.setOrderUseQuantity(add);
            saleContractManagementMapper.updateById(gSaleContractManagement);
        }
        BigDecimal countTotal = BigDecimal.ZERO;
        for (GSaleOrderProduct gSaleOrderProduct : gSaleOrderManagement.getSaleOrderProductList()) {
            if (gSaleOrderProduct.getOrderQuantity() == null) {
                throw new ServiceException(SaleErrorCode.NO_QUALITY.getCode(), SaleErrorCode.NO_QUALITY.getMsg());
            }
            countTotal = countTotal.add(gSaleOrderProduct.getOrderQuantity());
        }

        gSaleOrderManagement.setTotalQuantity(countTotal);
        gSaleOrderManagement.setPendingDelivery(countTotal);
        gSaleOrderManagement.setDelivered(BigDecimal.ZERO);

        if (StringUtils.isNotEmpty(gSaleOrderManagement.getRelatedMultipleOrders())) {
            GSaleOrderManagement saleOrderManagement1 = baseMapper.selectById(gSaleOrderManagement.getRelatedMultipleOrders());
            BigDecimal delivered = saleOrderManagement1.getDelivered().subtract(saleOrderManagement1.getTotalQuantity());
            if (saleOrderManagement.getTotalQuantity().compareTo(delivered) < 0) {
                throw new ServiceException(SaleErrorCode.UNION_ORDER_MORE_ORDER.getCode(), SaleErrorCode.UNION_ORDER_MORE_ORDER.getMsg());
            } else {
                gSaleOrderManagement.setDelivered(delivered);
                saleOrderManagement1.setCollectionStatus(Constants.TWO_STR);
                baseMapper.updateById(saleOrderManagement1);
            }
        }

        gSaleOrderManagement.setReturnQuantity(BigDecimal.ZERO);
        gSaleOrderManagement.setExchangeQuantity(BigDecimal.ZERO);
//        baseMapper.updateById(saleOrderManagement);
        fileApi.deleteByBusinessId(gSaleOrderManagement.getId());
        gSaleOrderManagement.setCreateUserId(saleOrderManagement.getCreateUserId());
        if (CollectionUtils.isNotEmpty(gSaleOrderManagement.getFileList())) {
            FileBusiness fileBusiness = new FileBusiness();
            fileBusiness.setFileIds(gSaleOrderManagement.getFileList());
            fileBusiness.setBusinessId(gSaleOrderManagement.getId());
            fileApi.updateBusinessById(fileBusiness);
        }
        if (CollectionUtils.isNotEmpty(gSaleOrderManagement.getSaleOrderProductList())) {
            gSaleOrderProductMapper.delete(Wrappers.<GSaleOrderProduct>lambdaQuery().eq(GSaleOrderProduct::getOrderId, gSaleOrderManagement.getId()));
            List<GSaleOrderProduct> saleOrderProductList = gSaleOrderManagement.getSaleOrderProductList();
            for (GSaleOrderProduct gSaleOrderProduct : saleOrderProductList) {
                gSaleOrderProduct.setOrderId(gSaleOrderManagement.getId());
                gSaleOrderProductMapper.insert(gSaleOrderProduct);
            }
        }
        baseMapper.updateById(gSaleOrderManagement);
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(Arrays.asList(gSaleOrderManagement.getId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGSaleOrderManagementByNumber(GSaleOrderManagement gSaleOrderManagement) {
        GSaleOrderManagement saleOrderManagement = baseMapper.selectOne(Wrappers.<GSaleOrderManagement>lambdaQuery().eq(GSaleOrderManagement::getOrderNumber, gSaleOrderManagement.getOrderNumber()).last("limit 1"));
        if (gSaleOrderManagement.getDelivered().compareTo(saleOrderManagement.getPendingDelivery()) >= 0) {
            saleOrderManagement.setPendingDelivery(BigDecimal.ZERO);
            if (saleOrderManagement.getDelivered() != null) {
                BigDecimal add = saleOrderManagement.getDelivered().add(gSaleOrderManagement.getDelivered());
                saleOrderManagement.setDelivered(add);
            } else {
                saleOrderManagement.setDelivered(gSaleOrderManagement.getDelivered());
            }
        } else {
            BigDecimal subtract = saleOrderManagement.getPendingDelivery().subtract(gSaleOrderManagement.getDelivered());
            saleOrderManagement.setPendingDelivery(subtract);
            if (saleOrderManagement.getDelivered() != null) {
                BigDecimal add = saleOrderManagement.getDelivered().add(gSaleOrderManagement.getDelivered());
                saleOrderManagement.setDelivered(add);
            } else {
                saleOrderManagement.setDelivered(gSaleOrderManagement.getDelivered());
            }
        }
        baseMapper.updateById(saleOrderManagement);

        //修改合同待发货数量
        GSaleContractManagement gSaleContractManagement = saleContractManagementMapper.selectById(saleOrderManagement.getContractId());
        if (gSaleContractManagement.getPendingDelivery() == null) {
            if (gSaleContractManagement.getOrderQuantity() != null) {
                if (gSaleContractManagement.getOrderQuantity().compareTo(gSaleOrderManagement.getDelivered()) >= 0) {
                    BigDecimal subtract = gSaleContractManagement.getOrderQuantity().subtract(gSaleOrderManagement.getDelivered());
                    gSaleContractManagement.setPendingDelivery(subtract);
                }
            }
        } else {
            if (gSaleContractManagement.getPendingDelivery().compareTo(gSaleOrderManagement.getDelivered()) >= 0) {
                BigDecimal subtract = gSaleContractManagement.getPendingDelivery().subtract(gSaleOrderManagement.getDelivered());
                gSaleContractManagement.setPendingDelivery(subtract);
            } else {
                gSaleContractManagement.setPendingDelivery(BigDecimal.ZERO);
            }
        }
        if (gSaleContractManagement.getDelivered() == null) {
            gSaleContractManagement.setDelivered(gSaleOrderManagement.getDelivered());
        } else {
            BigDecimal add = gSaleContractManagement.getDelivered().add(gSaleOrderManagement.getDelivered());
            gSaleContractManagement.setDelivered(add);
        }
        saleContractManagementMapper.updateById(gSaleContractManagement);
    }

    @Override
    public GSaleOrderManagement getGSaleOrderManagement(String id) {
        GSaleOrderManagement gSaleOrderManagement = baseMapper.selectById(id);
        List<GSaleOrderProduct> gSaleOrderProducts = gSaleOrderProductMapper.selectList(Wrappers.
                <GSaleOrderProduct>lambdaQuery().eq(GSaleOrderProduct::getOrderId, id));
        gSaleOrderManagement.setSaleOrderProductList(gSaleOrderProducts);
        ResultBody<List<String>> fileIdsByBusinessId = fileApi.getFileIdsByBusinessId(id);
        List<String> list = fileIdsByBusinessId.getData();
        gSaleOrderManagement.setFileList(list);

        if (StringUtils.isNotEmpty(gSaleOrderManagement.getRelatedMultipleOrders())) {
            GSaleOrderManagement gSaleOrderManagement1 = baseMapper.selectById(gSaleOrderManagement.getRelatedMultipleOrders());
            gSaleOrderManagement.setRelatedMultipleOrdersNumber(gSaleOrderManagement1.getOrderNumber());
        }
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(Arrays.asList(gSaleOrderManagement.getId()));
        Map<String, BpmProcessInstanceStatus> processMap = null;
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            processMap = resultBody.getData().stream().collect(Collectors.toMap(bp -> bp.getBusinessKey(), bp -> bp, (bp1, bp2) -> bp1));
            if (processMap != null) {
                if (processMap.get(gSaleOrderManagement.getId()) != null) {
                    gSaleOrderManagement.setNodeName(processMap.get(gSaleOrderManagement.getId()).getNodeName());
                }
            }
        }
        return gSaleOrderManagement;
    }

    @Override
    public IPage<GSaleOrderManagementDTO> getNewPage(GSaleOrderReq gSaleOrderReq) {
        return baseMapper.getNewPage(new Page<>(gSaleOrderReq.getPageNo(), gSaleOrderReq.getPageSize()), gSaleOrderReq);
    }

    @Override
    public void orderExport(GSaleOrderReq gSaleOrderReq, HttpServletResponse response) {
        String fileName = "销售订单报表" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss") + ".xlsx";
        try {
            // 对文件名进行URL编码
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");

            // 设置响应内容类型和字符编码
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");

            // 设置Content-Disposition头部，告诉浏览器这是一个文件下载请求
            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);

            // 获取导出数据
            IPage<GSaleOrderManagementDTO> checkList = baseMapper.getNewPage(new Page<GSaleOrderManagementDTO>(0L, 2000L), gSaleOrderReq);
            List<GSaleOrderManagementDTO> list = checkList.getRecords();

            // 使用EasyExcel写入数据到响应输出流
            EasyExcel.write(response.getOutputStream(), GSaleContractManagementDTO.class).excelType(ExcelTypeEnum.XLSX).sheet("销售订单报表").doWrite(list);

            // 刷新输出流
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
            // 处理异常，例如设置错误状态码或错误消息
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "导出Excel时发生错误");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }

    @Override
    public SaleBalanceGoods getGSaleToBeSettledDTODetail(String id) {
        GSaleOrderManagement gSaleOrderManagement = baseMapper.selectById(id);
        if (gSaleOrderManagement != null) {
            List<GSaleOrderProduct> gSaleOrderProducts = gSaleOrderProductMapper.selectList(Wrappers.<GSaleOrderProduct>lambdaQuery().eq(GSaleOrderProduct::getOrderId, id));
            SaleBalanceGoods saleBalanceGoods = new SaleBalanceGoods();
            BigDecimal needAmount = BigDecimal.ZERO;
            GSaleContractManagement gSaleContractManagement = saleContractManagementMapper.selectById(gSaleOrderManagement.getContractId());
            List<SaleBalanceGoodsDetail> saleBalanceGoodsDetailList = new ArrayList<>();
            BeanUtils.copyProperties(gSaleOrderManagement, saleBalanceGoods);
            for (GSaleOrderProduct gSaleOrderProduct : gSaleOrderProducts) {
                if (gSaleOrderProduct.getOrderQuantity() != null && gSaleOrderProduct.getGrossUnitPrice() != null) {
                    BigDecimal multiply = gSaleOrderProduct.getOrderQuantity().multiply(gSaleOrderProduct.getGrossUnitPrice());
                    needAmount = needAmount.add(multiply);
                }
                SaleBalanceGoodsDetail saleBalanceGoodsDetail = new SaleBalanceGoodsDetail();
                BeanUtils.copyProperties(gSaleOrderProduct, saleBalanceGoodsDetail);
                saleBalanceGoodsDetail.setContractName(saleBalanceGoods.getContractName());
                saleBalanceGoodsDetail.setOrderNumber(gSaleOrderManagement.getOrderNumber());
                saleBalanceGoodsDetail.setContractNumber(gSaleContractManagement.getNumber());
                saleBalanceGoodsDetailList.add(saleBalanceGoodsDetail);
            }
            saleBalanceGoods.setStayInvoicedAmount(needAmount.toString());
            saleBalanceGoods.setNeedAmount(needAmount.toString());
            saleBalanceGoods.setInvoicedAmount(BigDecimal.ZERO.toString());
            saleBalanceGoods.setReceivedAmount(BigDecimal.ZERO.toString());
            saleBalanceGoods.setSaleBalanceGoodsDetailList(saleBalanceGoodsDetailList);
            return saleBalanceGoods;
        }
        GSaleReturnInventory gSaleReturnInventory = saleReturnInventoryMapper.selectById(id);
        SaleBalanceGoods saleBalanceGoods = new SaleBalanceGoods();
        saleBalanceGoods.setConsigneeCustomer(gSaleReturnInventory.getCustomerId());
        List<SaleReturnInventoryProduct> saleReturnInventoryProductList = saleReturnInventoryProductMapper.selectList(Wrappers.<SaleReturnInventoryProduct>lambdaQuery().eq(SaleReturnInventoryProduct::getInventoryId, id));
        BigDecimal needAmount = BigDecimal.ZERO;
        List<SaleBalanceGoodsDetail> saleBalanceGoodsDetailList = new ArrayList<>();
        for (SaleReturnInventoryProduct saleReturnInventoryProduct : saleReturnInventoryProductList) {
            SaleBalanceGoodsDetail saleBalanceGoodsDetail = new SaleBalanceGoodsDetail();
            GSaleOrderManagement gSaleOrderManagement1 = baseMapper.selectOne(Wrappers.<GSaleOrderManagement>lambdaQuery().eq(GSaleOrderManagement::getOrderNumber, saleReturnInventoryProduct.getOrderNumber()).last("limit 1"));
            GSaleOrderProduct saleOrderProduct = gSaleOrderProductMapper.selectOne(Wrappers.<GSaleOrderProduct>lambdaQuery().eq(GSaleOrderProduct::getOrderId, gSaleOrderManagement1.getId())
                    .eq(GSaleOrderProduct::getProductId, saleReturnInventoryProduct.getProductId())
                    .last("limit 1")
            );
            if (saleOrderProduct.getOrderQuantity() != null && saleOrderProduct.getGrossUnitPrice() != null) {
                BigDecimal multiply = saleOrderProduct.getOrderQuantity().multiply(saleOrderProduct.getGrossUnitPrice());
                needAmount = needAmount.add(multiply);
            }
            BeanUtils.copyProperties(saleOrderProduct, saleBalanceGoodsDetail);
            saleBalanceGoodsDetail.setContractName(gSaleOrderManagement1.getContractName());
            saleBalanceGoodsDetail.setContractNumber(gSaleOrderManagement1.getContractNumber());
            saleBalanceGoodsDetail.setOrderNumber(gSaleOrderManagement1.getOrderNumber());
            saleBalanceGoodsDetail.setOutNumber(gSaleReturnInventory.getReturnNumber());
            saleBalanceGoodsDetail.setOrderQuantity(saleReturnInventoryProduct.getReturnQuantity());
            saleBalanceGoodsDetail.setNetAmount(saleReturnInventoryProduct.getReturnTotal());
            saleBalanceGoodsDetail.setGrossUnitPrice(saleOrderProduct.getGrossUnitPrice());
            if (saleOrderProduct != null) {
                saleBalanceGoodsDetail.setTaxRate(saleOrderProduct.getTaxRate());
                saleBalanceGoodsDetail.setUnit(saleOrderProduct.getUnit());
                saleBalanceGoodsDetail.setBulkDiscountPrice(saleOrderProduct.getBulkDiscountPrice());
                saleBalanceGoodsDetail.setConsigneeAddress(saleOrderProduct.getConsigneeAddress());
            }
            saleBalanceGoodsDetailList.add(saleBalanceGoodsDetail);
        }
        saleBalanceGoods.setStayInvoicedAmount(needAmount.toString());
        saleBalanceGoods.setNeedAmount(needAmount.toString());
        saleBalanceGoods.setInvoicedAmount(BigDecimal.ZERO.toString());
        saleBalanceGoods.setReceivedAmount(BigDecimal.ZERO.toString());
        saleBalanceGoods.setSaleBalanceGoodsDetailList(saleBalanceGoodsDetailList);
        return saleBalanceGoods;
    }


    @Override
    @RedissonLock(key = MATERIAL_IN_WAREHOUSE_NUMBER, prefixKey = "lock_")
    public String generateNextSerialNumber() {
        String orderNumber = "";
        Serializable number = rediservice.get(MATERIAL_ORDER_WAREHOUSE_NUMBER);
        if (number == null || StringUtils.isBlank(number.toString())) {
            ResultBody<String> resultBody = portalApi.getValueByCode(MATERIAL_ORDER_WAREHOUSE_NUMBER);
            if (resultBody != null && StringUtils.isNotBlank(resultBody.getData())) {
                number = resultBody.getData();
                orderNumber = SerialOrderNumberGenerator.generateNextSerialNumber(number.toString());
            } else {
                orderNumber = SerialOrderNumberGenerator.generateNextSerialNumber(null);
            }
        } else {
            orderNumber = SerialOrderNumberGenerator.generateNextSerialNumber(number.toString());
        }
        rediservice.set(MATERIAL_ORDER_WAREHOUSE_NUMBER, orderNumber);
        DictInfo info = new DictInfo();
        info.setCsdm(MATERIAL_ORDER_WAREHOUSE_NUMBER);
        info.setCsmc(orderNumber);
        portalApi.updateValueByCode(info);
        return orderNumber;
    }


    @RedissonLock(key = MATERIAL_SHPPING_WAREHOUSE_NUMBER, prefixKey = "lock_")
    public String getMaterialShppingNumber() {
        String date = LocalDate.now().format(DateTimeFormatter.ofPattern(CommonConstant.DATE_FORMAT_UN_SEPARATE));
        date = "M".concat(date);
        String code = "";

        Serializable number = rediservice.get(RedisKey.MATERIAL_SHPPING_WAREHOUSE_NUMBER);
        if (number == null || StringUtils.isBlank(number.toString())) {
            ResultBody<String> resultBody = portalApi.getValueByCode(SALE_OUT_NUMBER);
            if (resultBody != null && StringUtils.isNotBlank(resultBody.getData())) {
                number = resultBody.getData();
            }
        }
        if (number != null && StringUtils.isNotBlank(number.toString()) && number.toString().length() > 9) {
            String sequenceStr = number.toString().substring(9);
            int sequenceInt = Integer.parseInt(sequenceStr);
            sequenceInt = sequenceInt + 1;
            String newSequence = String.valueOf(sequenceInt);
            if (newSequence.length() == CommonConstant.FIVE_INT) {
                code = date.concat("0001");
            } else {
                code = date.concat(String.format("%04d", sequenceInt)); // 格式化数字为4位，不足部分用0填充
            }
        } else {
            code = date.concat("0001");
        }
        rediservice.set(RedisKey.MATERIAL_SHPPING_WAREHOUSE_NUMBER, code);
        DictInfo info = new DictInfo();
        info.setCsdm(RedisKey.MATERIAL_SHPPING_WAREHOUSE_NUMBER);
        info.setCsmc(code);
        portalApi.updateValueByCode(info);
        return code;
    }
}
